#ifdef INHERIT_FROM_DELEGATE_STREAM
#ifdef strType
/*
#define INHERIT_FROM_MODEL_MOUNTSTREAM		\
  _pcb* pro;					\
  STRFUNC_(_dsop)* ope;				\
		 INHERIT_FROM_DELEGATE_STREAM

#include "stream_model/model_mountStream.h"
*/
#include "struct_delegateStream.h"

					  
//#define _ConvertToPub __ConvertToPub
//#define _ConvertToPrv __ConvertToPrv
#define _WriteStream __WriteStream
#define _ReadStream  __ReadStream
#define _SeekStream  __SeekStream
#define _PeekStream  __PeekStream
#define _CombineStream  __CombineStream
#define _ApartStream  __ApartStream
#define _EndStream  __EndStream
#define _MountStream __MountStream
#define _UnmountStream __UnmountStream
#define _NameStream  __NameStream
#define _IOStream  __IOStream
#define _GetStreamLength __GetStreamLength	  
					  
#define __ConvertToPub_(x)  ((x)->ope->__ConvertToPub) 
#define __ConvertToPrv_(x)  ((x)->ope->__ConvertToPrv)
#define __CombineStream_(x) ((x)->ope->__CombineStream != NULL?(x)->ope->__CombineStream:0)
#define __ApartStream_(x)   ((x)->ope->__ApartStream != NULL?(x)->ope->__ApartStream:0)
#define __MountStream_(x)   ((x)->ope->__MountStream)
#define __UnmountStream_(x) ((x)->ope->__UnmountStream)
#define __NameStream_(x)    ((x)->ope->__NameStream)
#define __IOStream_(x)	    ((x)->ope->__IOStream)
					  
//#define STATE_CHANGE(stream,num) _STATE_CHANGE_(stream,num)

static _ptlong _ConvertToPub(strType from, _dfps to, _length num, _length offset)
{
  _tcb* server = BuildThread(from->pro,__ConvertToPub_(from));
  //BuildThread is to create a thread control block.
  STRFUNC(AddStreamTo)(to,server);
  _ptlong argvs[] = {(_ptlong)from,(_ptlong)to,EXPAND_LENGTH_MEMBER(num),EXPAND_LENGTH_MEMBER(offset)};

  //There is problem -- if the sizeof(_length) if not 4 bytes, we have to extend it into u32
  ArgvThread(server,argvs,sizeof(argvs)/sizeof(_ptlong));
  //ArgvThread is to Set the running entrance and push argvs into the stack
  return RunThread(server);
  //RunThread is simply put thread into the ring.
  
}


static _ptlong _ConvertToPrv(_dfps from, strType to, _length num, _length offset)
{
  _tcb* server = BuildThread(to->pro,__ConvertToPrv_(to));
  STRFUNC(AddStreamTo)(to,server);
  _ptlong argvs[]={(_ptlong)from,(_ptlong)to,EXPAND_LENGTH_MEMBER(num),EXPAND_LENGTH_MEMBER(offset)};
  //There is another problem: u32 maybe is not the _ptlong
  ArgvThread(server,argvs,sizeof(argvs)/sizeof(_ptlong));
  return RunThread(server);
}

static _ptlong __MountStream(strType stream, strType root)
{
  if(__MountStream_ == NULL)
	return 1;
  _tcb* server = BuildThread(root->pro,__MountStream_(stream));
  _ptlong argvs[]={(_ptlong)stream,(_ptlong)root};
  ArgvThread(server,argvs,sizeof(argvs)/sizeof(_ptlong));
  return RunThread(server);
}
  


static _ptlong __UnmountStream(strType stream, strType root)
{
  if(__UnmountStream_ == NULL)
	return 1;
  _tcb* server = BuildThread(root->pro,__UnmountStream_(stream));
  _ptlong argvs[]={(_ptlong)stream,(_ptlong)root};
  //There is problem -- if the sizeof(_length) if not 4 bytes, we have to extend it into u32
  ArgvThread(server,argvs,sizeof(argvs)/sizeof(_ptlong));
  return RunThread(server);
}


static _ptlong __NameStream(char* streamName, strType stream)
{
  if(__NameStream_ == NULL)
	return 1;
  _tcb* server = BuildThread(stream->pro,__NameStream_(stream));
  _ptlong argvs[]={(_ptlong)streamName,(_ptlong)root};
  //There is problem -- if the sizeof(_length) if not 4 bytes, we have to extend it into u32
  ArgvThread(server,argvs,sizeof(argvs)/sizeof(_ptlong));
  return RunThread(server);
}



#ifndef __WriteStream
static strType __WriteStream(strType stream, u8* input, _length num, _length offset)
{
  _dfps halfway = _DFPSOP(CreateStream)();
  _ConvertToPrv(halfway,stream,num,offset);
  _DFSOP(WriteStream)(halfway,input,num,offset);
  _DFSOP(EndStream)(halfway);
  return stream;
}

#endif

#ifndef __ReadStream
static strType __ReadStream(strType stream, u8* output, _length num, _length offset)
{
  _dfps halfway = _DFSOP(CreateStream)();
  _ConvertToPub(stream, halfway, num, offset);
  _DFSOP(ReadStream)(halfway,output,num,offset);
  _DFSOP(EndStream)(halfway);
  return stream;
}


#endif

#ifndef __PeekStream
static strType __PeekStream(strType stream, u8* output, _length num, _length offset)
{
  __ReadStream(stream,output,num,offset);
}
#endif

static int __CombineStream(strType to,strType from)
{
  if(__CombineStream_(to) == 0)
    __CombineStream_Default(to,from);
  else
    {
      _tcb* server =  BuildThread(to->pro,__CombineStream_(to));
      u32 argv[] = {(u32)to,(u32)from};
      ArgvThread(server,argv,sizeof(argv)/sizeof(u32));
	RunStream(server);
    }
}


static _ptlong __ApartStream(strType from,strType to, _length offset)
{
  if(__ApartStream_(to) == 0)
    __ApartStream_Default(from,to,offset);
  else
    {
      _tcb* server =  BuildThread(from->pro,__CombineStream_(to));
      u32 argv[] = {(u32)from,(u32)to,EXPAND_LENGTH_MEMBER(offset)};
      //There is problem -- if the sizeof(_length) if not 4 bytes, we have to extend it into u32
      ArgvThread(server,argv,sizeof(argv)/sizeof(u32));
	RunStream(server);
    }
}

static _ptlong __IOStream(_dfps from,strType to,_length num,_length offset)
{
  if(__IOStream_(to) != 0)
    {
      _tcb* server =  BuildThread(from->pro,__IOStream_(to));
      u32 argv[] = {(u32)from,(u32)to,EXPAND_LENGTH_MEMBER(num),EXPAND_LENGTH_MEMBER(offset)};
      //There is problem -- if the sizeof(_length) if not 4 bytes, we have to extend it into u32
      ArgvThread(server,argv,sizeof(argv)/sizeof(u32));    
	RunStrean(server);  
      return 1;
    }
  else
    return 0;
}



static _ptlong __CombineStream_Default(strType to,strType from)
{
  _dfps buffA = _DFSOP(CreateStream)();
  _dfps buffB = _DFSOP(CreateStream)();
  _ConvertToPub(to,buffA,UNLIMITED,0);
  _ConvertToPub(from,buffB,UNLIMITED,0);
  _DFSOP(CombineStream)(buffA,buffB);
  _ConvertToPrv(buffA,to,UNLIMITED,0);
}

static _ptlong __ApartStream_Default(strType from, strType to, _length offset)
{
  _dfps buffA = _DFSOP(CreateStream)();
  _dfps buffB = _DFSOP(CreateStream)();
  _ConvertToPub(from,buffA,offset,0);
  _ConvertToPub(from,buffB,UNLIMITED,offset);
  _ConvertToPrv(buffA,from,UNLIMITED,0);
  _ConvertToPrv(buffB,to,UNLIMITED,0);
}


_ptlong STRFUNC(DelegateStream)(strType stream,_pcb* pro, STRFUNC_(_dsop)* operations)
{
  stream->pro = pro;
  stream->ope = operations;
  //operations is in the user space , but the delegated thread is runned in user mode in the applicant process,
  // so it can be found and runned safely
  return 1;
}

#endif
#endif
